using System;
using System.Collections.Generic;
using System.Xml;
using System.Linq;

namespace IMSAT.OFTD.DOM.DataProxy.Xml
{
    public class XmlProxyReader:IProxyReader<XmlReader>
    {
        public IDataNode Read(XmlReader source)
        {
            IDataNode curent=null;
            Stack<IDataNode> parents = new Stack<IDataNode>();
            while (source.Read())
            {
                if(source.NodeType == XmlNodeType.EndElement)
                {
                    if (parents.Count > 0)
                    {
                        curent = parents.Pop();
                    }
                }
                else if(source.NodeType == XmlNodeType.Element)
                {
                    var tmp = new DataCollection(new List<IDataNode>(), source.LocalName);
                    tmp.Add(new DataLeaf("namespace", source.NamespaceURI));
                    try
                    {
                        new XmlReaderAttributeEnumerable(source)
                            .Select(
                            rd => new DataLeaf(rd.Name, rd.Value)
                            )
                            .Aggregate(tmp, (cool, node) =>
                            {
                                cool.Add(node);
                                return cool;
                            }
                            );
                    }
                    catch (Exception exception)
                    {
                        throw new ApplicationException("!", exception);
                    }
                    if (curent != null)
                    {
                        ((DataCollection)curent).Add(tmp);
                        if (!source.IsEmptyElement)
                        {
                            parents.Push(curent);
                            curent = tmp;
                            
                        }
                    }
                    else
                    {
                        curent = tmp;
                    }
                }
            }
            return curent;
        }
    }
}